package invalidcomponentgeneralization;

import invalidcomponentgeneralization.InvalidComponentGeneralizationMatch;
import java.util.Collection;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.viatra2.emf.incquery.runtime.api.EngineManager;
import org.eclipse.viatra2.emf.incquery.runtime.api.IMatchProcessor;
import org.eclipse.viatra2.emf.incquery.runtime.api.IMatcherFactory;
import org.eclipse.viatra2.emf.incquery.runtime.api.IncQueryEngine;
import org.eclipse.viatra2.emf.incquery.runtime.api.IncQueryMatcher;
import org.eclipse.viatra2.emf.incquery.runtime.api.impl.BaseGeneratedMatcher;
import org.eclipse.viatra2.emf.incquery.runtime.exception.IncQueryRuntimeException;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.misc.DeltaMonitor;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.Tuple;
import sysmodel.BusinessComponent;
import sysmodel.RestComponent;

/**
 * Generated pattern matcher API of the InvalidComponentGeneralization pattern, 
 * providing pattern-specific query methods.
 * 
 * 
 * 
 * // ------------------------------------------------------------------------------------------------------------
 * // Filter invalid component generalizations. E.g. (Rest -> Business)
 * // Satisfied constraint:
 * //     	- Business component can only inherited from business component
 * //		- Rest component can only inherited from rest component
 * @Constraint(message=\"$component1.name$ rest component and $component2.name$ business component should not be in the same generalization path!\", severity=\"error\", location=\"component1\")
 * pattern InvalidComponentGeneralization(component1 : RestComponent, component2 : BusinessComponent) = {
 * 	find ComponentGeneralizationPath(component1, component2);
 * } or { 
 * 	find ComponentGeneralizationPath(component2, component1);
 * }
 * 
 * @see InvalidComponentGeneralizationMatch
 * @see InvalidComponentGeneralizationMatcherFactory
 * @see InvalidComponentGeneralizationProcessor
 * 
 */
public class InvalidComponentGeneralizationMatcher extends BaseGeneratedMatcher<InvalidComponentGeneralizationMatch> implements IncQueryMatcher<InvalidComponentGeneralizationMatch> {
  /**
   * Initializes the pattern matcher over a given EMF model root (recommended: Resource or ResourceSet). 
   * If a pattern matcher is already constructed with the same root, only a lightweight reference is created.
   * The match set will be incrementally refreshed upon updates from the given EMF root and below.
   * <p>Note: if emfRoot is a resourceSet, the scope will include even those resources that are not part of the resourceSet but are referenced. 
   * This is mainly to support nsURI-based instance-level references to registered EPackages.
   * @param emfRoot the root of the EMF tree where the pattern matcher will operate. Recommended: Resource or ResourceSet.
   * @throws IncQueryRuntimeException if an error occurs during pattern matcher creation
   * 
   */
  public InvalidComponentGeneralizationMatcher(final Notifier notifier) throws IncQueryRuntimeException {
    this(EngineManager.getInstance().getIncQueryEngine(notifier));
  }
  
  /**
   * Initializes the pattern matcher within an existing EMF-IncQuery engine. 
   * If the pattern matcher is already constructed in the engine, only a lightweight reference is created.
   * The match set will be incrementally refreshed upon updates.
   * @param engine the existing EMF-IncQuery engine in which this matcher will be created.
   * @throws IncQueryRuntimeException if an error occurs during pattern matcher creation
   * 
   */
  public InvalidComponentGeneralizationMatcher(final IncQueryEngine engine) throws IncQueryRuntimeException {
    super(engine, FACTORY);
  }
  
  /**
   * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters.
   * @param pComponent1 the fixed value of pattern parameter component1, or null if not bound.
   * @param pComponent2 the fixed value of pattern parameter component2, or null if not bound.
   * @return matches represented as a InvalidComponentGeneralizationMatch object.
   * 
   */
  public Collection<InvalidComponentGeneralizationMatch> getAllMatches(final RestComponent pComponent1, final BusinessComponent pComponent2) {
    return rawGetAllMatches(new Object[]{pComponent1, pComponent2});
    
  }
  
  /**
   * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters.
   * Neither determinism nor randomness of selection is guaranteed.
   * @param pComponent1 the fixed value of pattern parameter component1, or null if not bound.
   * @param pComponent2 the fixed value of pattern parameter component2, or null if not bound.
   * @return a match represented as a InvalidComponentGeneralizationMatch object, or null if no match is found.
   * 
   */
  public InvalidComponentGeneralizationMatch getOneArbitraryMatch(final RestComponent pComponent1, final BusinessComponent pComponent2) {
    return rawGetOneArbitraryMatch(new Object[]{pComponent1, pComponent2});
    
  }
  
  /**
   * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match,
   * under any possible substitution of the unspecified parameters (if any).
   * @param pComponent1 the fixed value of pattern parameter component1, or null if not bound.
   * @param pComponent2 the fixed value of pattern parameter component2, or null if not bound.
   * @return true if the input is a valid (partial) match of the pattern.
   * 
   */
  public boolean hasMatch(final RestComponent pComponent1, final BusinessComponent pComponent2) {
    return rawHasMatch(new Object[]{pComponent1, pComponent2});
    
  }
  
  /**
   * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters.
   * @param pComponent1 the fixed value of pattern parameter component1, or null if not bound.
   * @param pComponent2 the fixed value of pattern parameter component2, or null if not bound.
   * @return the number of pattern matches found.
   * 
   */
  public int countMatches(final RestComponent pComponent1, final BusinessComponent pComponent2) {
    return rawCountMatches(new Object[]{pComponent1, pComponent2});
    
  }
  
  /**
   * Executes the given processor on each match of the pattern that conforms to the given fixed values of some parameters.
   * @param pComponent1 the fixed value of pattern parameter component1, or null if not bound.
   * @param pComponent2 the fixed value of pattern parameter component2, or null if not bound.
   * @param processor the action that will process each pattern match.
   * 
   */
  public void forEachMatch(final RestComponent pComponent1, final BusinessComponent pComponent2, final IMatchProcessor<? super InvalidComponentGeneralizationMatch> processor) {
    rawForEachMatch(new Object[]{pComponent1, pComponent2}, processor);
    
  }
  
  /**
   * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters.  
   * Neither determinism nor randomness of selection is guaranteed.
   * @param pComponent1 the fixed value of pattern parameter component1, or null if not bound.
   * @param pComponent2 the fixed value of pattern parameter component2, or null if not bound.
   * @param processor the action that will process the selected match. 
   * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked
   * 
   */
  public boolean forOneArbitraryMatch(final RestComponent pComponent1, final BusinessComponent pComponent2, final IMatchProcessor<? super InvalidComponentGeneralizationMatch> processor) {
    return rawForOneArbitraryMatch(new Object[]{pComponent1, pComponent2}, processor);
    
  }
  
  /**
   * Registers a new filtered delta monitor on this pattern matcher.
   * The DeltaMonitor can be used to track changes (delta) in the set of filtered pattern matches from now on, considering those matches only that conform to the given fixed values of some parameters. 
   * It can also be reset to track changes from a later point in time, 
   * and changes can even be acknowledged on an individual basis. 
   * See {@link DeltaMonitor} for details.
   * @param fillAtStart if true, all current matches are reported as new match events; if false, the delta monitor starts empty.
   * @param pComponent1 the fixed value of pattern parameter component1, or null if not bound.
   * @param pComponent2 the fixed value of pattern parameter component2, or null if not bound.
   * 	 @return the delta monitor.
   * 
   */
  public DeltaMonitor<InvalidComponentGeneralizationMatch> newFilteredDeltaMonitor(final boolean fillAtStart, final RestComponent pComponent1, final BusinessComponent pComponent2) {
    return rawNewFilteredDeltaMonitor(fillAtStart, new Object[]{pComponent1, pComponent2});
    
  }
  
  @Override
  public InvalidComponentGeneralizationMatch tupleToMatch(final Tuple t) {
    try {
    	return new InvalidComponentGeneralizationMatch((sysmodel.RestComponent) t.get(0), (sysmodel.BusinessComponent) t.get(1));	
    } catch(ClassCastException e) {System.err.println("Error when executing tupleToMatch in InvalidComponentGeneralizationMatcher:" + e.getMessage());
    	//throw new IncQueryRuntimeException(e.getMessage());
    	return null;
    }
    
  }
  
  @Override
  public InvalidComponentGeneralizationMatch arrayToMatch(final Object[] match) {
    try {
    	return new InvalidComponentGeneralizationMatch((sysmodel.RestComponent) match[0], (sysmodel.BusinessComponent) match[1]);
    } catch(ClassCastException e) {System.err.println("Error when executing arrayToMatch in InvalidComponentGeneralizationMatcher:" + e.getMessage());
    }
    		//throw new IncQueryRuntimeException(e.getMessage());
    		return null;
    
  }
  
  public final static IMatcherFactory<InvalidComponentGeneralizationMatch,InvalidComponentGeneralizationMatcher> FACTORY =  new InvalidComponentGeneralizationMatcherFactory();
}
